#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <assert.h>

#include "log.h"
#include "activation_profile.h"

#define BUF_SIZE 8192

#define PROFILE_ETC "/etc/kylin-activation/activation_conf.ini"
#define PROFILE_TMP "/tmp/kylin-activation/activation_conf.ini"
#define PROFILE_USR "/usr/share/kylin-activation/activation_conf.ini"

//注意：以后增加或修改的配置项需要同步在defaule_profile中修改
GKeyFile *activation_default_profile()
{
    GKeyFile *default_keyfile = NULL;
    GKeyFileFlags flags;
    GError *error = NULL;
    unsigned char default_data[BUF_SIZE];

    memset(default_data, 0, sizeof(default_data));
    flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
    default_keyfile = g_key_file_new();

    g_key_file_load_from_data (default_keyfile, default_data, strlen(default_data), flags, &error);
    if (error != NULL) {
        log_msg("error: %s\n", error->message);
        g_error_free (error);
    }

    g_key_file_set_value(default_keyfile, "KMS_Activation", "ServerIp", "");
    g_key_file_set_value(default_keyfile, "KMS_Activation", "UDP_Port", "");
    g_key_file_set_value(default_keyfile, "KMS_Activation", "TCP_Port", "");

    g_key_file_set_value(default_keyfile, "Sent_Server", "register", "");
    g_key_file_set_value(default_keyfile, "Sent_Server", "status", "");
    g_key_file_set_value(default_keyfile, "Sent_Server", "serial", "");
    g_key_file_set_value(default_keyfile, "Sent_Server", "harddisk_id", "");
    g_key_file_set_value(default_keyfile, "Sent_Server", "system_uuid", "");
    g_key_file_set_value(default_keyfile, "Sent_Server", "interface_mac", "");
    g_key_file_set_value(default_keyfile, "Sent_Server", "current_active", "");

    g_key_file_set_value(default_keyfile, "MODE_Activation", "cloud_virtual_desktop", "false");

    if ( NULL != error )
        g_error_free(error);

    return default_keyfile;
}

gboolean activation_old_profile_restore(GKeyFile *default_keyfile)
{
    assert(default_keyfile != NULL);

    gsize length;
    gboolean is_restored = FALSE;
    gchar **tmp_groups = NULL, **tmp_keys = NULL;
    gchar **default_groups = NULL, **default_keys = NULL;
    GKeyFileFlags flags;
    GError *error = NULL;
    GKeyFile *tmp_keyfile = NULL;

    flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;

    tmp_keyfile = g_key_file_new();
    g_key_file_load_from_file (tmp_keyfile, PROFILE_TMP, flags, &error);
    if(NULL != error) {
        log_msg("error: %s\n", error->message);
        return is_restored;
    }

    default_groups = g_key_file_get_groups(default_keyfile, &length);
    if ( 0 == length || NULL == default_groups ) {
        log_msg("%s is empty\n", PROFILE_TMP);
        return is_restored;
    } else {
        while(*default_groups) {
            default_keys = g_key_file_get_keys(default_keyfile, *default_groups, &length, &error);
            if (NULL == default_keys) {
                log_msg("current group: %s, keys is empty.\n", *default_groups);
                continue;
            }

            if (g_key_file_has_group(tmp_keyfile, *default_groups)) {
                while(*default_keys) {
                    gchar *default_value = g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL);
                    if (g_key_file_has_key(tmp_keyfile, *default_groups,*default_keys,NULL)) {
                        gchar *tmp_value = g_key_file_get_value(tmp_keyfile,*default_groups,*default_keys,NULL);
                        if ( (NULL == tmp_value || strlen(tmp_value) == 0) && ( NULL != default_value && strlen(default_value) != 0) ) {
                            g_key_file_set_value(tmp_keyfile,
                                                 *default_groups,
                                                 *default_keys,
                                                 g_key_file_get_value(tmp_keyfile,*default_groups,*default_keys,NULL));
                            log_msg("Set tmp file: [ %s / %s ] = %s \n", \
                                    *default_groups,
                                    *default_keys,
                                    g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                            is_restored = TRUE;
                        }
                    } else {
                        g_key_file_set_value(tmp_keyfile,
                                             *default_groups,
                                             *default_keys,
                                             g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                        log_msg("Set tmp file key none: [ %s / %s ] = %s \n", \
                                *default_groups,
                                *default_keys,
                                g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                        is_restored = TRUE;
                    }
                    default_keys++;
                }
            } else {
                while(*default_keys) {
                    g_key_file_set_value(tmp_keyfile,
                                         *default_groups,
                                         *default_keys,
                                         g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                    log_msg("Set tmp file group none: [ %s / %s ] = %s \n", \
                            *default_groups,
                            *default_keys,
                            g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                    is_restored = TRUE;
                    default_keys++;
                }
            }
            default_groups++;
        }
    }

    if (is_restored) {
       g_key_file_save_to_file(tmp_keyfile, PROFILE_ETC, &error);
       if (error != NULL) {
           log_msg("error: %s\n", error->message);
       } else {
           log_msg("save to file %s success\n", PROFILE_ETC);
       }
    }

    gchar *contents = g_key_file_to_data (tmp_keyfile, &length, NULL);
    log_msg("contents tmp conf: \n%s\n", contents);

    if ( NULL != error )
        g_error_free(error);

    //NOTE: 删掉tmp
   if ( 0 == access(PROFILE_TMP,F_OK)) {
       if ( 0 == remove(PROFILE_TMP) ) {
           log_msg("remove success: %s\n", PROFILE_TMP);
       } else {
           log_msg("remove error: %s\n", PROFILE_TMP);
       }
   }

   if ( 0 == access("/tmp/kylin-activation",F_OK)) {
       if ( 0 == rmdir("/tmp/kylin-activation") ) {
           log_msg("remove success: %s\n", "/tmp/kylin-activation");
       } else {
           log_msg("remove error: %s\n", "/tmp/kylin-activation");
       }
   }

    return is_restored;
}

gboolean activation_etc_profile_restore(GKeyFile *etc_keyfile, GKeyFile *default_keyfile)
{
    assert(etc_keyfile != NULL);

    gsize length;
    gboolean is_restored = FALSE;
    gchar **default_groups = NULL, **default_keys = NULL;
    GKeyFileFlags flags;
    GError *error = NULL;

    flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;

    default_groups = g_key_file_get_groups(default_keyfile, &length);
    if ( 0 == length || NULL == default_groups ) {
        log_msg("%s is empty\n", PROFILE_ETC);
        return is_restored;
    } else {
        while(*default_groups) {
            default_keys = g_key_file_get_keys(default_keyfile, *default_groups, &length, &error);
            if (NULL == default_keys) {
                log_msg("current group: %s, keys is empty.\n", *default_groups);
                continue;
            }

            if (g_key_file_has_group(etc_keyfile, *default_groups)) {
                while(*default_keys) {
                    gchar *tmp_value = g_key_file_get_value(default_keyfile, *default_groups, *default_keys, NULL);
                    if (g_key_file_has_key(etc_keyfile, *default_groups, *default_keys,NULL)) {
                        gchar *etc_value = g_key_file_get_value(etc_keyfile, *default_groups, *default_keys, NULL);
                        if ( (NULL == etc_value || strlen(etc_value) == 0) && ( NULL != tmp_value && strlen(tmp_value) != 0) ) {
                            g_key_file_set_value(etc_keyfile,
                                                 *default_groups,
                                                 *default_keys,
                                                 g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                            log_msg("current grounp: %s, key_name:%s, key_value: %s\n", \
                                    *default_groups,
                                    *default_keys,
                                    g_key_file_get_value(etc_keyfile,*default_groups,*default_keys,NULL));
                            is_restored = TRUE;
                        }
                    } else {
                        g_key_file_set_value(etc_keyfile,
                                             *default_groups,
                                             *default_keys,
                                             g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                        log_msg("current grounp: %s, key_name:%s, key_value: %s\n", \
                                *default_groups,
                                *default_keys,
                                g_key_file_get_value(etc_keyfile,*default_groups,*default_keys,NULL));
                        is_restored = TRUE;
                    }
                    default_keys++;
                }
            } else {
                while(*default_keys) {
                    g_key_file_set_value(etc_keyfile,
                                         *default_groups,
                                         *default_keys,
                                         g_key_file_get_value(default_keyfile,*default_groups,*default_keys,NULL));
                    log_msg("current grounp: %s, key_name:%s, key_value: %s\n", \
                            *default_groups,
                            *default_keys,
                            g_key_file_get_value(etc_keyfile,*default_groups,*default_keys,NULL));
                    is_restored = TRUE;
                    default_keys++;
                }
            }
            default_groups++;
        }
    }

    if (is_restored) {
        g_key_file_save_to_file(etc_keyfile, PROFILE_ETC, &error);
        if (error != NULL) {
            log_msg("error: %s\n", error->message);
        } else {
            log_msg("save to file %s success\n", PROFILE_ETC);
        }
    }

    if ( NULL != error )
        g_error_free(error);

    return is_restored;
}

void activation_default_profile_init()
{
    if( access(PROFILE_ETC,F_OK) != 0 )
        log_msg("Can't find file: %s\n", PROFILE_ETC);

    gsize length;
    gchar **default_groups = NULL, **default_keys = NULL;
    GKeyFileFlags flags;
    GError *error = NULL;
    GKeyFile *default_keyfile = NULL, *etc_keyfile = NULL;

    flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;

    default_keyfile = activation_default_profile();

    etc_keyfile  = g_key_file_new();
    if ( !g_key_file_load_from_file(etc_keyfile, PROFILE_ETC, flags, &error) ) {
        if(NULL != error)
            log_msg("error: %s\n", error->message);
        else
            log_msg("load profile error: %s\n", PROFILE_ETC);
        return ;
    }

    // default_groups = g_key_file_get_groups(default_keyfile, &length);
    // gchar *contents = g_key_file_to_data (default_keyfile, &length, NULL);
    // log_msg("contents default conf: \n%s\n", contents);

    // contents = g_key_file_to_data (etc_keyfile, &length, NULL);
    // log_msg("contents etc conf: \n%s\n", contents);

    if( access(PROFILE_TMP,F_OK) != 0 ) {
        log_msg("Can't find file: %s\n", PROFILE_TMP);
        activation_etc_profile_restore(etc_keyfile, default_keyfile);
    } else {
        log_msg("Find old profile: %s\n", PROFILE_TMP);
        activation_old_profile_restore(default_keyfile);
    }

    //Soft-connection
    if( (access(PROFILE_USR,F_OK) != 0) && (access(PROFILE_ETC,F_OK) == 0) ) {
        log_msg("Soft-connection creating .\n");
        if(symlink(PROFILE_ETC, PROFILE_USR) == -1)
            log_msg("Error creating symlink .\n");
        else
            log_msg("Symlink created successfully.\n");
    }
}
